import pygame
import math
import random

# 初始化pygame
pygame.init()

# 设置窗口尺寸
WIDTH, HEIGHT = 1200, 700
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("动态粒子爱心")

# 定义爱心形状的参数方程
def heart(t, scale=10.0):
    x = 16 * (math.sin(t) ** 3) * scale
    y = (13 * math.cos(t) - 5 * math.cos(2 * t) - 2 * math.cos(3 * t) - math.cos(4 * t)) * scale
    return x, y

# 可选的辅助：径向渐变（目前不用于底部显示，仅保留以备调整）
def make_glow(radius, color, max_alpha=140):
    surf = pygame.Surface((radius * 2, radius * 2), pygame.SRCALPHA)
    cx = cy = radius
    for r in range(radius, 0, -1):
        normalized = r / radius
        a = int(max_alpha * (1 - normalized) ** 1.6)
        if a <= 0:
            continue
        col = (color[0], color[1], color[2], a)
        pygame.draw.circle(surf, col, (cx, cy), r)
    return surf

# 粒子类（从发射点发射，逐渐被吸引到爱心曲线上并发光、闪烁）
class Particle:
    def __init__(self, base_pos, heart_scale):
        self.max_life = random.uniform(2.0, 4.5)  # 秒
        self.life = self.max_life
        self.x, self.y = base_pos
        angle = random.uniform(-math.pi/2, math.pi/2)
        speed = random.uniform(1.5, 6.0)
        self.vx = math.cos(angle) * speed * 0.6 + random.uniform(-1, 1)
        self.vy = -abs(math.sin(angle) * speed) - random.uniform(0, 2.0)  # 向上偏移
        self.t = random.uniform(0, 2 * math.pi)
        self.heart_scale = heart_scale * random.uniform(0.85, 1.2)
        base_b = random.randint(180, 255)
        self.color = (random.randint(50, 120), random.randint(120, 200), base_b)
        self.size = random.uniform(1.5, 3.8)
        self.phase = random.uniform(0, 2 * math.pi)

    def update(self, dt):
        self.life -= dt
        # 基础移动
        self.x += self.vx * dt * 60
        self.y += self.vy * dt * 60

        # 渐进向心形靠拢
        self.t += 0.5 * dt
        tx, ty = heart(self.t, scale=self.heart_scale)
        tx += WIDTH / 2
        ty = HEIGHT / 2 - ty

        life_ratio = max(0.01, self.life / self.max_life)
        attraction = (1.0 - life_ratio) * 0.12 + 0.01
        self.x += (tx - self.x) * attraction
        self.y += (ty - self.y) * attraction

        # 轻微扰动
        self.x += math.sin(self.phase + self.life * 10) * 0.3
        self.y += math.cos(self.phase + self.life * 8) * 0.3

    def draw_to(self, surf):
        life_ratio = max(0.0, min(1.0, self.life / self.max_life))
        flicker = 0.6 + 0.4 * (0.5 + 0.5 * math.sin(self.phase + (1 - life_ratio) * 20))
        alpha = int(255 * (1 - life_ratio ** 1.5) * flicker)
        color = (self.color[0], self.color[1], self.color[2], alpha)
        r = max(1, int(self.size * (0.6 + (1 - life_ratio) * 1.6)))
        p = pygame.Surface((r * 4, r * 4), pygame.SRCALPHA)
        pygame.draw.circle(p, color, (r * 2, r * 2), r)
        surf.blit(p, (int(self.x - r * 2), int(self.y - r * 2)), special_flags=pygame.BLEND_ADD)

# 管理粒子系统
class ParticleSystem:
    def __init__(self, count, base_pos, heart_scale):
        self.base_pos = base_pos
        self.heart_scale = heart_scale
        self.particles = []
        self.count = count
        self.add_surf = pygame.Surface((WIDTH, HEIGHT), pygame.SRCALPHA)

    def emit(self):
        # 从心形附近或中心发射（无可见底座）
        while len(self.particles) < self.count:
            # 在发射点附近随机偏移一点
            px = self.base_pos[0] + random.uniform(-50, 50)
            py = self.base_pos[1] + random.uniform(-10, 40)
            p = Particle((px, py), self.heart_scale)
            self.particles.append(p)

    def update_and_draw(self, dt, target_surface):
        self.add_surf.fill((0, 0, 0, 0))
        alive = []
        for p in self.particles:
            p.update(dt)
            if p.life > 0:
                p.draw_to(self.add_surf)
                alive.append(p)
        self.particles = alive
        target_surface.blit(self.add_surf, (0, 0), special_flags=pygame.BLEND_ADD)
        self.emit()

# 初始化系统与参数
clock = pygame.time.Clock()
running = True

# 发射点：放在屏幕中下方但不要绘制底座（不会绘制任何实体）
# 发射点可微调：越靠近 HEART 中心，粒子更快成形
base_center = (WIDTH // 2, int(HEIGHT * 0.88))  # 仅做发射源，不绘制可视底座
base_radius = 150
glow_color = (50, 160, 255)

ps = ParticleSystem(count=900, base_pos=base_center, heart_scale=9.2)

# 半透明覆盖实现拖尾
fade_surf = pygame.Surface((WIDTH, HEIGHT), pygame.SRCALPHA)
fade_surf.fill((0, 0, 0, 60))

# 主循环（仅保留爱心粒子与拖尾）
while running:
    dt = clock.tick(60) / 1000.0
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

    screen.blit(fade_surf, (0, 0))

    # 更新并绘制粒子（不绘制底座）
    ps.update_and_draw(dt, screen)

    # 偶发小星星增强效果
    if random.random() < 0.06:
        sx = base_center[0] + random.uniform(-120, 120)
        sy = base_center[1] - random.uniform(40, 260)
        rad = random.randint(1, 3)
        col = (180, 230, 255, 220)
        ptemp = pygame.Surface((rad*4, rad*4), pygame.SRCALPHA)
        pygame.draw.circle(ptemp, col, (rad*2, rad*2), rad)
        screen.blit(ptemp, (int(sx - rad*2), int(sy - rad*2)), special_flags=pygame.BLEND_ADD)

    pygame.display.flip()

pygame.quit()
